]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
shell-recorder: Use clutter-computed sizes and scaling for the capture
authorMarco Trevisan (Treviño) <mail@3v1n0.net>
Sat, 23 Dec 2017 03:54:48 +0000 (04:54 +0100)
committerJonas Ådahl <jadahl@gmail.com>
Fri, 1 Mar 2019 17:12:53 +0000 (17:12 +0000)
Get from clutter the capture sizes and scale and don't mind
about doing any rounding here, as it might be different
from the one done at clutter level (causing mismatch and
not-working videos). Delegate this to clutter, and forget
about the internal details.

These values are then used to composte the image and set the video caps.

https://bugzilla.gnome.org/show_bug.cgi?id=7650111

src/shell-recorder.c
src/shell-screenshot.c
src/shell-util.c
src/shell-util.h

index 9bf36e6db41d4ea310523d38a5daac77eaf7757f..c2e83412cd493a617b4a50756a0836ed7feae3f9 100644 (file)
@@ -51,6 +51,10 @@ struct _ShellRecorder {
   int stage_width;
   int stage_height;
 
+  int capture_width;
+  int capture_height;
+  float scale;
+
   int pointer_x;
   int pointer_y;
 
@@ -430,10 +434,8 @@ recorder_record_frame (ShellRecorder *recorder,
     return;
   recorder->last_frame_time = now;
 
-  clutter_stage_capture (recorder->stage, paint, &recorder->area,
-                         &captures, &n_captures);
-
-  if (n_captures == 0)
+  if (!clutter_stage_capture (recorder->stage, paint, &recorder->area,
+                              &captures, &n_captures))
     return;
 
   if (n_captures == 1)
@@ -443,8 +445,9 @@ recorder_record_frame (ShellRecorder *recorder,
                                                  n_captures,
                                                  recorder->area.x,
                                                  recorder->area.y,
-                                                 recorder->area.width,
-                                                 recorder->area.height);
+                                                 recorder->capture_width,
+                                                 recorder->capture_height,
+                                                 recorder->scale);
 
   data = cairo_image_surface_get_data (image);
   size = (cairo_image_surface_get_height (image) *
@@ -500,6 +503,11 @@ recorder_update_size (ShellRecorder *recorder)
       recorder->area.y = 0;
       recorder->area.width = recorder->stage_width;
       recorder->area.height = recorder->stage_height;
+
+      clutter_stage_get_capture_final_size (recorder->stage, NULL,
+                                            &recorder->capture_width,
+                                            &recorder->capture_height,
+                                            &recorder->scale);
     }
 }
 
@@ -618,6 +626,8 @@ recorder_connect_stage_callbacks (ShellRecorder *recorder)
                     G_CALLBACK (recorder_on_stage_notify_size), recorder);
   g_signal_connect (recorder->stage, "notify::height",
                     G_CALLBACK (recorder_on_stage_notify_size), recorder);
+  g_signal_connect (recorder->stage, "notify::resource-scale",
+                    G_CALLBACK (recorder_on_stage_notify_size), recorder);
 }
 
 static void
@@ -875,6 +885,7 @@ shell_recorder_class_init (ShellRecorderClass *klass)
 static void
 recorder_pipeline_set_caps (RecorderPipeline *pipeline)
 {
+  ShellRecorder *recorder = pipeline->recorder;
   GstCaps *caps;
 
   /* The data is always native-endian xRGB; videoconvert
@@ -887,9 +898,9 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline)
 #else
                               "format", G_TYPE_STRING, "xRGB",
 #endif
-                              "framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
-                              "width", G_TYPE_INT, pipeline->recorder->area.width,
-                              "height", G_TYPE_INT, pipeline->recorder->area.height,
+                              "framerate", GST_TYPE_FRACTION, recorder->framerate, 1,
+                              "width", G_TYPE_INT, recorder->capture_width,
+                              "height", G_TYPE_INT, recorder->capture_height,
                               NULL);
   g_object_set (pipeline->src, "caps", caps, NULL);
   gst_caps_unref (caps);
@@ -1496,6 +1507,11 @@ shell_recorder_set_area (ShellRecorder *recorder,
   recorder->area.height = CLAMP (height,
                                  0, recorder->stage_height - recorder->area.y);
 
+  clutter_stage_get_capture_final_size (recorder->stage, &recorder->area,
+                                        &recorder->capture_width,
+                                        &recorder->capture_height,
+                                        &recorder->scale);
+
   /* This breaks the recording but tweaking the GStreamer pipeline a bit
    * might make it work, at least if the codec can handle a stream where
    * the frame size changes in the middle.
index 4a119a1530bc09b38e94a3a2eb897f66805a6802..125af823ee4f7a64235105cda56dcb621a0478e5 100644 (file)
@@ -222,29 +222,32 @@ do_grab_screenshot (ShellScreenshot *screenshot,
                     int               height)
 {
   ShellScreenshotPrivate *priv = screenshot->priv;
+  cairo_rectangle_int_t screenshot_rect = { x, y, width, height };
   ClutterCapture *captures;
   int n_captures;
   int i;
 
-  clutter_stage_capture (stage, FALSE,
-                         &(cairo_rectangle_int_t) {
-                           .x = x,
-                           .y = y,
-                           .width = width,
-                           .height = height
-                         },
-                         &captures,
-                         &n_captures);
-
-  if (n_captures == 0)
+  if (!clutter_stage_capture (stage, FALSE,
+                              &screenshot_rect,
+                              &captures,
+                              &n_captures))
     return;
-  else if (n_captures == 1)
+
+  if (n_captures == 1)
     priv->image = cairo_surface_reference (captures[0].image);
   else
-    priv->image = shell_util_composite_capture_images (captures,
-                                                       n_captures,
-                                                       x, y,
-                                                       width, height);
+    {
+      float target_scale;
+
+      clutter_stage_get_capture_final_size (stage, &screenshot_rect,
+                                            &width, &height, &target_scale);
+      priv->image = shell_util_composite_capture_images (captures,
+                                                         n_captures,
+                                                         x, y,
+                                                         width, height,
+                                                         target_scale);
+    }
+
   priv->datetime = g_date_time_new_now_local ();
 
   for (i = 0; i < n_captures; i++)
index 95d9f8e142a158061f55b68b4b70310a180a8140..88a9ce11e953e9c87d501d280ad23de24bb7234d 100644 (file)
@@ -462,31 +462,20 @@ shell_util_composite_capture_images (ClutterCapture  *captures,
                                      int              n_captures,
                                      int              x,
                                      int              y,
-                                     int              width,
-                                     int              height)
+                                     int              target_width,
+                                     int              target_height,
+                                     float            target_scale)
 {
   int i;
-  double target_scale;
   cairo_format_t format;
   cairo_surface_t *image;
   cairo_t *cr;
 
   g_assert (n_captures > 0);
-
-  target_scale = 0.0;
-  for (i = 0; i < n_captures; i++)
-    {
-      ClutterCapture *capture = &captures[i];
-      double capture_scale = 1.0;
-
-      cairo_surface_get_device_scale (capture->image, &capture_scale, NULL);
-      target_scale = MAX (target_scale, capture_scale);
-    }
+  g_assert (target_scale > 0.0f);
 
   format = cairo_image_surface_get_format (captures[0].image);
-  image = cairo_image_surface_create (format,
-                                      width * target_scale,
-                                      height * target_scale);
+  image = cairo_image_surface_create (format, target_width, target_height);
   cairo_surface_set_device_scale (image, target_scale, target_scale);
 
   cr = cairo_create (image);
index 914f438d2030528b0faa843c248e85f5be1b0a25..6904f43bc3157a0073ef1eb123205d5258ef0f06 100644 (file)
@@ -53,8 +53,9 @@ cairo_surface_t * shell_util_composite_capture_images (ClutterCapture  *captures
                                                        int              n_captures,
                                                        int              x,
                                                        int              y,
-                                                       int              width,
-                                                       int              height);
+                                                       int              target_width,
+                                                       int              target_height,
+                                                       float            target_scale);
 
 void shell_util_check_cloexec_fds (void);